panic したときに Drop が実行される様子を見る
きっかけ
外部システムとのやりとりをするテストがあり,assertionに失敗してもそれをクリーンアップしたいんだけど,どうすればいい?という質問に,Drop を使えと返している
↓
下の例では,外部システムの例としてファイルシステムを触っている
CleanupGuard構造体を作り,それの Drop::drop にファイルを削除する処理を書いている
main 関数とテストの両方に,クリーンアップガードありでパニックする処理を書いた
cargo run と cargo test のどちらを実行しても,パニック時にきちんとファイルが消去される
→panic 時でも Drop が実行される
code:sample.rs
use std::io::Write;
use std::{fs::File, path::PathBuf};
struct CleanupGuard {
file_path: PathBuf,
}
impl Drop for CleanupGuard {
fn drop(&mut self) {
use std::fs::remove_file;
// クリーンアップ処理:ファイルを削除
if self.file_path.exists() {
remove_file(&self.file_path).expect("Failed to delete temp file");
}
}
}
fn main() {
let tmp_file_path = PathBuf::from("temp_test_file.txt");
let _guard = CleanupGuard {
file_path: tmp_file_path.clone(),
};
{
let mut file = File::create(&tmp_file_path).expect("Failed to create temp file");
writeln!(file, "Hello, world!").expect("Failed to write to temp file");
panic!();
}
}
mod tests {
fn test_file_system_interaction() {
use super::CleanupGuard;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
// テスト用の一時ファイルパスを設定
let tmp_file_path = PathBuf::from("temp_test_file.txt");
// クリーンアップガードを作成
let _guard = CleanupGuard {
file_path: tmp_file_path.clone(),
};
// 外部システムとのやり取りをシミュレート(ファイルに書き込み)
{
let mut file = File::create(&tmp_file_path).expect("Failed to create temp file");
writeln!(file, "Hello, world!").expect("Failed to write to temp file");
}
panic!();
}
}